<?php
/**
 * Note: *
 */

namespace App\Services;

use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class Ip138Service
{
    private const API_QUERY = 'http://api.ipshudi.com/ipdata/';

    protected static $configs = [];

    protected static function getConfig($key = null)
    {
        if (!self::$configs) self::$configs = config('services.ip138');

        return $key ? (self::$configs[$key] ?? null) : self::$configs;
    }

    /**
     * 发送get请求
     * @param $url
     * @param null $data
     * @param array $header
     * @return Response
     * @throws \Exception
     */
    protected static function requestGet($url, $data = null, array $header = []): Response
    {
        // 发生错误时 100ms 后重试 1 次, 每次超时3s (设置timeout之后, 如果超时会直接抛出异常, 不到 $response->throw), 这里放入try
        try {
            info(__METHOD__, [$url, $data]);
            $response = Http::retry(2, 100)->timeout(3)->withHeaders($header)->get($url, $data);
            $response->throw();
            info(__METHOD__, [$response]);
        } catch (\Exception $e) {
            report($e);
            throw new \Exception("IP查询服务正在维护中，请联系客服");
        }
        return $response;
    }

    /**
     * 统一查询
     * @param string $ip
     * @param int $action
     * @return bool
     * @throws \Exception
     */
    public static function isWarning(string $ip, int $action = IpAddrService::ACTION_REG): bool
    {
        $response = self::requestGet(self::API_QUERY.'?datatype=json&ip='.$ip, null, ['token' => self::getConfig('token')]);
        if ($response['ret'] !== 'ok') {
            throw new \Exception('查询失败');
        }

        // $response['data'][0] 国
        // $response['data'][1] 省
        // $response['data'][2] 城市
        // $response['data'][3] 区、县
        // $response['data'][4] 运营商
        // $response['data'][5] 邮编
        // $response['data'][6] 区号
        $country = $response['data'][0] ?? '';
        $province = $response['data'][1] ?? '';
        $areaNo = $response['data'][6] ?? '0';

        // 区分注册事件和登录事件
        if ($action === IpAddrService::ACTION_REG) {
            return Str::contains($province, '广西');
        } else if ($action === IpAddrService::ACTION_LOGIN) {
            return Str::contains($province, '广西');
        } else if ($action === IpAddrService::ACTION_LOGIN_ADMIN) {
            return !in_array($areaNo, ['021', '0571', '0579', '0512']) && !Str::contains($country, '美国');
        }
        return false;
    }
}
